package cn.lbd.kill.server.controller;

import cn.lbd.kill.api.enums.StatusCode;
import cn.lbd.kill.api.response.BaseResponse;
import cn.lbd.kill.model.dto.KillSuccessUserInfo;
import cn.lbd.kill.model.mapper.ItemKillSuccessMapper;
import cn.lbd.kill.server.dto.KillDTO;
import cn.lbd.kill.server.enums.SysConstant;
import cn.lbd.kill.server.service.KillService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;

@Controller
public class KillController {
    private static final Logger log = LoggerFactory.getLogger(KillController.class);

    private static final String prefix = "kill";

    @Autowired
    private KillService killService;

    @Autowired(required = false)
    private ItemKillSuccessMapper itemKillSuccessMapper;

    /**
     * 抢购
     *
     * @param dto    数据传输对象。1.实体类做了JSR303校验，所以要配上Validated注解；2.从请求体中获取内容，内容是秒杀ID和用户ID
     * @param result 封装了校验结果，是JSR303帮我们封装的
     * @return
     */
    //MediaType.APPLICATION_JSON_UTF8_VALUE => "application/json;charset=UTF-8"
    @RequestMapping(value = prefix + "/execute", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public BaseResponse execute(@RequestBody @Validated KillDTO dto, BindingResult result, HttpSession session) {
        //判断字段是否通过校验，以及传入的killId是否合法
        if (result.hasErrors() || dto.getKillId() <= 0) {
            return new BaseResponse(StatusCode.InvalidParams);
        }
        //用户登陆后将用户id塞入shiro的session，从session获取秒杀要用的id，为空说明用户未登录
        Object uId = session.getAttribute("uid");
        if (session.getAttribute("uid") == null) {
            return new BaseResponse(StatusCode.UserNotLogin);
        }
        Integer userId = (Integer) uId;
        System.out.println("================================" + userId);
        BaseResponse response = new BaseResponse(StatusCode.Success);
        log.info("秒杀开始.....");
        System.out.println("miaoshakaishi秒杀开始");
        try {
            //秒杀成功就返回True
            /*Boolean res = killService.killItem(dto.getKillId(), dto.getUserId());*/
            //Boolean res = killService.killItemV2(dto.getKillId(), dto.getUserId());
            //Boolean res = killService.killItemV3(dto.getKillId(), dto.getUserId());
            Boolean res = killService.killItemV4(dto.getKillId(), userId);
            if (!res) {
                return new BaseResponse(StatusCode.Fail.getCode(), "哈哈~商品已抢购完毕或者不在抢购时间段哦!");
            }
        } catch (Exception e) {
            //捕获service层向上抛出的异常，提交给页面提示
            response = new BaseResponse(StatusCode.Fail.getCode(), e.getMessage());
            e.printStackTrace();
        }
        System.out.println(response.getMsg() + "==============================");
        return response;
    }

    /**
     * 用于压力测试的秒杀接口
     * @param dto
     * @param result
     * @param session
     * @return
     */
    @RequestMapping(value = prefix + "/execute/lock", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public BaseResponse executeTest(@RequestBody @Validated KillDTO dto, BindingResult result, HttpSession session) {
        //判断字段是否通过校验，以及传入的killId是否合法
        if (result.hasErrors() || dto.getKillId() <= 0) {
            return new BaseResponse(StatusCode.InvalidParams);
        }
        //用户登陆后将用户id塞入shiro的session，从session获取秒杀要用的id，为空说明用户未登录
        /*Object uId = session.getAttribute("uid");
        if (session.getAttribute("uid") == null) {
            return new BaseResponse(StatusCode.UserNotLogin);
        }
        Integer userId = (Integer) uId;*/
        BaseResponse response = new BaseResponse(StatusCode.Success);
        log.info("秒杀开始.....");
        System.out.println("秒杀开始");
        try {
            //秒杀成功就返回True
            //Boolean res = killService.killItem(dto.getKillId(), dto.getUserId());
            //Redis分布式锁优化
            //Boolean res = killService.killItemV2(dto.getKillId(), dto.getUserId());
            //Redisson分布式锁优化
            //Boolean res = killService.killItemV3(dto.getKillId(), dto.getUserId());
            //Zookeeper分布式锁优化
            Boolean res = killService.killItemV4(dto.getKillId(), dto.getUserId());
            if (!res) {
                return new BaseResponse(StatusCode.Fail.getCode(), "哈哈~商品已抢购完毕或者不在抢购时间段哦!");
            }
        } catch (Exception e) {
            //捕获service层向上抛出的异常，提交给页面提示
            response = new BaseResponse(StatusCode.Fail.getCode(), e.getMessage());
            e.printStackTrace();
        }
        System.out.println(response.getMsg() + "==============================");
        return response;
    }

    /**
     * 邮件通知中的页面跳转
     */
    @RequestMapping(value = prefix + "/record/detail/{orderNo}", method = RequestMethod.GET)
    public String toKillRecord(@PathVariable String orderNo, Model model) {
        if (orderNo != null) {
            KillSuccessUserInfo killSuccessUserInfo = itemKillSuccessMapper.selectByCode(orderNo);
            if (killSuccessUserInfo != null) {
                model.addAttribute("info", killSuccessUserInfo);
            }
        }
        return "killRecord";
    }

    /**
     * 秒杀成功的跳转
     */
    @RequestMapping(value = prefix + "/execute/success", method = RequestMethod.GET)
    public String executeSuccess() {
        return "executeSuccess";
    }


    /**
     * 秒杀失败的跳转
     */
    @RequestMapping(value = prefix + "/execute/fail", method = RequestMethod.GET)
    public String executeFail() {
        return "executeFail";
    }
}
